(defpackage #:basic-actions
  (:use :cl)
  (:export #:before-step-hook
           #:before-undo-hook))

(in-package #:basic-actions)

(defclass basic-actions ()
  ())

(exp:define-action toggle-selection ((trial basic-actions)
                                     (e:click-node :var id)
                                     (bt:select-mode))
  (let ((node (d:find-id-or-die (d:root (p:diagram trial)) id)))
    (p:toggle-selection trial node)
    (setf (gwee:view-needs-update-p (p:diagram trial)) t)))

(exp:define-action keypad-input ((state basic-actions)
                                 (kp:keypad-input :var input-string)
                                 (fill-mode))
  (exp:lg 'keypress :char input-string)
  (with-slots (input) state
    (when input
      (if (char= kp:keypad-input #\Return)
          (progn
            (keypad:submit input)
            (setf input nil))
          (keypad:add-input input input-string)))))

(exp:define-action navigate ((state basic-actions)
                             (exp:click :source :back))
  (p:navigate state :back 'update-after-navigate))

(exp:define-action navigate ((state basic-actions)
                             (exp:click :source :forward))
  (p:navigate state :forward 'update-after-navigate))

(exp:define-action navigate ((state basic-actions)
                             (exp:click :source :first-mistake))
  (p:navigate state :first-mistake 'update-after-navigate))

(exp:define-action help ((state basic-actions)
                         (exp:click :source :help))
  (bt:turn-on-hints-for-stage state))

(exp:define-action next-problem ((state basic-actions)
                                 (exp:click :source :next-problem))
  (p:next-problem state))

(exp:define-action operation ((state basic-actions)
                              (click-operation :var op)
                              (select-mode))
  (p:do-operation state op))

(exp:define-action operation ((state basic-actions)
                              (click-operation :var op)
                              (fill-mode))
  (exp:lg 'operation :name op :successful nil)
  (p:display-message state :error "Operations cannot be performed while there are input boxes."))

